package com.lancoo.ccas53.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lancoo.ccas53.entity.College;
import com.lancoo.ccas53.entity.CollegeRoom;
import com.lancoo.ccas53.entity.TaskInfo;
import com.lancoo.ccas53.exception.BizException;
import com.lancoo.ccas53.mapper.CollegeMapper;
import com.lancoo.ccas53.pojo.common.PageInfo;
import com.lancoo.ccas53.pojo.excel.ExcelCollegeRoom;
import com.lancoo.ccas53.pojo.response.basicPlatform.BaseCollege;
import com.lancoo.ccas53.pojo.vo.CollegeRoomInput;
import com.lancoo.ccas53.pojo.vo.CollegeRoomVo;
import com.lancoo.ccas53.service.CollegeRoomService;
import com.lancoo.ccas53.service.CollegeService;
import com.lancoo.ccas53.service.ScheduleService;
import com.lancoo.ccas53.service.TaskInfoService;
import com.lancoo.ccas53.util.MyExcelUtils;
import com.lancoo.ccas53.util.PagingUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 院系及提交时间 服务实现类
 * </p>
 *
 * @author quin.song
 * @since 2024-05-20
 */
@Service
public class CollegeServiceImpl extends ServiceImpl<CollegeMapper, College> implements CollegeService {

    @Resource
    private CollegeRoomService collegeRoomService;
    @Resource
    private CollegeMapper collegeMapper;


    @Resource
    private ScheduleService scheduleService;


    @Resource
    private TaskInfoService taskInfoService;


    @Override
    @Transactional
    public void syncColleges(Integer taskId, List<BaseCollege> baseCollege) {
        List<College> colleges = new ArrayList<>();
        //防止重复
        List<String> collect = this.lambdaQuery().eq(College::getTaskId, taskId).list().stream().map(College::getBaseCollegeId).collect(Collectors.toList());
        for (BaseCollege college : baseCollege) {
            if (collect.contains(college.getCollegeID())) {
                continue;
            }
            colleges.add(new College()
                    .setTaskId(taskId)
                    .setBaseCollegeId(college.getCollegeID())
                    .setCollegeName(college.getCollegeName())
            );
        }
        if (CollUtil.isNotEmpty(colleges)) {
            this.saveBatch(colleges);
        }
    }

    @Override
    public List<CollegeRoomVo> getCollegeRoom(Integer taskId, String baseCollegeId, Integer roomSet) {
        List<College> collegeList = this.lambdaQuery()
                .eq(College::getTaskId, taskId)
                .eq(StringUtils.isNotBlank(baseCollegeId), College::getBaseCollegeId, baseCollegeId)
                .eq(ObjUtil.isNotNull(roomSet), College::getRoomSet, roomSet)
                .select(College::getBaseCollegeId, College::getCollegeName, College::getRoomSet)
                .list();
        List<CollegeRoomVo> collegeRoomVoList = BeanUtil.copyToList(collegeList, CollegeRoomVo.class);
        if (CollUtil.isNotEmpty(collegeRoomVoList)) {
            //添加上课场地
            List<String> collegeIds = collegeRoomVoList.stream().map(CollegeRoomVo::getBaseCollegeId).collect(Collectors.toList());
            collegeRoomService.lambdaQuery()
                    .eq(CollegeRoom::getTaskId, taskId)
                    .in(CollegeRoom::getBaseCollegeId, collegeIds)
                    .list()
                    .stream().collect(Collectors.groupingBy(CollegeRoom::getBaseCollegeId))
                    .forEach((k, v) -> {
                        collegeRoomVoList.forEach(collegeRoomVo -> {
                            if (collegeRoomVo.getBaseCollegeId().equals(k)) {
                                collegeRoomVo.setCollegeRooms(v);
                            }
                        });
                    });
        }

        return collegeRoomVoList;
    }

    @Override
    public Boolean setCollegeRoom(CollegeRoomInput collegeRoomInput) {
        //删除原有
        collegeRoomService.lambdaUpdate()
                .eq(CollegeRoom::getTaskId, collegeRoomInput.getTaskId())
                .in(CollegeRoom::getBaseCollegeId, collegeRoomInput.getBaseCollegeIds())
                .remove();

        //根据collegeRooms是否为null 修改院系分配状态
        if (CollUtil.isEmpty(collegeRoomInput.getCollegeRooms())) {
            this.lambdaUpdate()
                    .eq(College::getTaskId, collegeRoomInput.getTaskId())
                    .in(College::getBaseCollegeId, collegeRoomInput.getBaseCollegeIds())
                    .set(College::getRoomSet, 0)
                    .update();
        } else {
            //新增
            collegeRoomService.saveBatch(collegeRoomInput.getCollegeRooms());
            this.lambdaUpdate()
                    .eq(College::getTaskId, collegeRoomInput.getTaskId())
                    .in(College::getBaseCollegeId, collegeRoomInput.getBaseCollegeIds())
                    .set(College::getRoomSet, 1)
                    .update();
        }
        return true;
    }

    @Override
    public Boolean clearCollegeRoom(Integer taskId) {
        //获取已分配场地的学院id
        List<String> collegeIdList = this.lambdaQuery()
                .eq(College::getTaskId, taskId)
                .eq(College::getRoomSet, 1)
                .list()
                .stream().map(College::getBaseCollegeId).collect(Collectors.toList());
        //清空场地分配表
        if (collegeIdList != null && collegeIdList.size() != 0) {
            collegeRoomService.lambdaUpdate()
                    .eq(CollegeRoom::getTaskId, taskId)
                    .in(CollegeRoom::getBaseCollegeId, collegeIdList)
                    .remove();
            //同时修改college表中对应数据的分配状态
            List<College> list = this.lambdaQuery().eq(College::getTaskId, taskId).eq(College::getRoomSet, 1).list();
            list.stream().forEach(a -> {
                a.setRoomSet(0);
                collegeMapper.updateById(a);
            });

            //还原学院表
            this.lambdaUpdate()
                    .eq(College::getTaskId, taskId)
                    .in(College::getCollegeId, collegeIdList)
                    .set(College::getRoomSet, 0)
                    .update();
        }
        return true;
    }

    @Override
    public List<College> getCollage(Integer taskId) {
        return this.lambdaQuery().eq(College::getTaskId, taskId).list();
    }


    @Override
    public void exportSiteAllocationDerivation(HttpServletResponse response, Integer taskId, String baseCollegeId, Integer roomSet) {


        List<ExcelCollegeRoom> excelCollegeRooms = new ArrayList<>();


        TaskInfo taskInfo = taskInfoService.getById(taskId);

        College one = new College();
        if (StringUtils.isNotBlank(baseCollegeId)) {
            one = this.lambdaQuery().eq(College::getBaseCollegeId, baseCollegeId).one();
        }

        //构建标题
        String title = " {} {}场地分配导出" + "\n" + "是否分配:{}" + "\n" + "院系:{}";
        String format = StrUtil.format(title, taskInfo.getTermName(), taskInfo.getSchoolName()
                , ObjUtil.isNull(roomSet) ? "全部" : (roomSet.equals(1) ? "已分配" : "未分配"),
                StringUtils.isNotBlank(baseCollegeId) ? one.getCollegeName() : "全部");


        List<CollegeRoomVo> collegeRoom = this.getCollegeRoom(taskId, baseCollegeId, roomSet);

        collegeRoom.forEach(o -> {
            ExcelCollegeRoom excelCollegeRoom = new ExcelCollegeRoom();
            excelCollegeRoom.setDepartName(o.getCollegeName());
            excelCollegeRoom.setFlag(o.getRoomSet() == 1 ? "已分配" : "未分配");

            List<CollegeRoom> collegeRooms = o.getCollegeRooms();

            if (CollUtil.isNotEmpty(collegeRooms)) {
                List<String> rooms = new ArrayList<>();
                collegeRooms.forEach(c -> {
                    String s = c.getRoomName();
                    rooms.add(s);
                });
                String join = String.join(",", rooms);
                excelCollegeRoom.setCollegeRoomName(join);
            } else {
                excelCollegeRoom.setCollegeRoomName("");
            }
            excelCollegeRooms.add(excelCollegeRoom);
        });


        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));

        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");

        MyExcelUtils.exportExcel(excelCollegeRooms,
                format,
                "教学活动安排",
                ExcelCollegeRoom.class,
                "场地分配导出表" + time + ".xls", response);
    }

    @Override
    public PageInfo<College> getScheduleCommit(Page<College> page, Integer taskId, String baseCollegeId) {
        Page<College> collegePage = this.lambdaQuery().eq(College::getTaskId, taskId)
                .eq(StrUtil.isNotEmpty(baseCollegeId), College::getBaseCollegeId, baseCollegeId)
                .isNotNull(StrUtil.isNotEmpty(baseCollegeId), College::getScheduleArrLatestTime)
                .page(page);
        return PagingUtil.formatPageResult(collegePage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void scheduleCommit(Integer taskId, String baseCollegeId, String userId, String userName, Integer lock, Integer arrangeRound) throws UnsupportedEncodingException {
        if (lock == null || (lock != 1 && lock != 2)) {
            throw new BizException("非法参数 lock");
        }
        if (StrUtil.isNotEmpty(baseCollegeId)) {
            College college = this.lambdaQuery().eq(College::getTaskId, taskId)
                    .eq(College::getBaseCollegeId, baseCollegeId)
                    .one();
            college.setScheduleArrUserId(userId);
            college.setScheduleArrUserName(URLDecoder.decode(userName, "utf-8"));
            college.setScheduleArrLatestTime(LocalDateTime.now());
            if (college.getScheduleArrFirstTime() == null) {
                college.setScheduleArrFirstTime(LocalDateTime.now());
            }
            this.updateById(college);
        } else {
            //管理员锁定所有教学班
//            scheduleService.lockAll(taskId,baseCollegeId, lock, arrangeRound);
            scheduleService.lockUnLockAll(taskId, lock, arrangeRound);
        }
    }
}
